package com.h2.ref.server.web.social;

import org.springframework.social.connect.Connection;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;

import com.h2.ref.server.auth.AuthUtils;
import com.h2.ref.server.user.IUserService;
import com.h2.ref.server.user.model.User;
import com.h2.ref.server.web.ViewConstants;
import com.h2.ref.server.web.user.UserFormData;
import com.h2.ref.server.web.user.UserValidator;

@Controller
public class SocialUserRegistrationController {
   
   private ConnectionRepositoryInMem _connectionDao;
   
   private IUserService _userService;
   
   private Boolean _requireActivation = false;
   
   private String _defaultTargetUrl;
   
   ////
   ////
   
   @RequestMapping(value = ViewConstants.REGISTER_SOCIAL,
         method = RequestMethod.GET)
   public String profile(Model model) {
      UserFormData user = new UserFormData();
      model.addAttribute("user", user);
      return ViewConstants.REGISTER_SOCIAL_VIEW;
   }
   
   @RequestMapping(value = ViewConstants.REGISTER_SOCIAL,
         method = RequestMethod.POST)
   public String processSubmit(Model model,
            @ModelAttribute("user")
            UserFormData user, BindingResult binding,
            NativeWebRequest request) {
      
      UserValidator.validateName(user.getName(), binding);
      UserValidator.validateEmail(user.getUserDetails().getEmail(), binding);
      UserValidator.validateCode(user.getVerificationCode(), binding);
      
      if (binding.hasErrors()) {
         return ViewConstants.REGISTER_USER_VIEW;
      }
      else if(getUserService().findByUserName(user.getName()) != null) {
         binding.rejectValue("name", "register.user.invalid");
         return ViewConstants.REGISTER_USER_VIEW;
      }
      else if(getUserService().findByEmail(
            user.getUserDetails().getEmail()) != null) {
         binding.rejectValue("userDetails.email",
               "register.email.invalid.duplicate");
         return ViewConstants.REGISTER_SOCIAL_VIEW;
      }
      
      Connection<?> connection = (Connection<?>) request.getAttribute("socialConnection",
            RequestAttributes.SCOPE_SESSION);
      
      if (connection == null) {
         return ViewConstants.REDIRECT + ViewConstants.LOGIN_SOCIAL + ".html";
      }
      
      //add user
      User addedUser = getUserService().addRegisteredUser(user.copy(),
            !getRequireActivation());
      
      //add connection
      getConnectionDao().addConnection(addedUser, connection);
      
      if (getRequireActivation()) {
         return ViewConstants.REDIRECT + ViewConstants.LOGIN_SOCIAL + ".html";
      }
      else {
         AuthUtils.changeAuth(user.getName(), user.getPassword());
         return ViewConstants.REDIRECT + getDefaultTargetUrl();
      }
   }

   /**
    * @return the connectionDao
    */
   public ConnectionRepositoryInMem getConnectionDao() {
      return _connectionDao;
   }

   /**
    * @param connectionDao the connectionDao to set
    */
   public void setConnectionDao(ConnectionRepositoryInMem connectionDao) {
      _connectionDao = connectionDao;
   }

   /**
    * @return the userService
    */
   public IUserService getUserService() {
      return _userService;
   }

   /**
    * @param userService the userService to set
    */
   public void setUserService(IUserService userService) {
      _userService = userService;
   }

   /**
    * @return the requireActivation
    */
   public Boolean getRequireActivation() {
      return _requireActivation;
   }

   /**
    * @param requireActivation the requireActivation to set
    */
   public void setRequireActivation(Boolean requireActivation) {
      _requireActivation = requireActivation;
   }

   /**
    * @return the defaultTargetUrl
    */
   public String getDefaultTargetUrl() {
      return _defaultTargetUrl;
   }

   /**
    * @param defaultTargetUrl the defaultTargetUrl to set
    */
   public void setDefaultTargetUrl(String defaultTargetUrl) {
      _defaultTargetUrl = defaultTargetUrl;
   }

}
